<template>
  <el-dialog
    :title="!form.roleId ? '添加角色' : '修改角色'"
    :close-on-click-modal="false"
    v-model="isShow"
    width="600px"
    @close="close"
  >
    <el-form ref="rulesForm" :model="form" :rules="rules" label-width="80px">
      <div class="search-form2">
        <el-form-item label="角色名" prop="roleName">
          <el-input v-model="form.roleName"></el-input>
        </el-form-item>
        <el-form-item label="权限字符" prop="roleKey">
          <el-input v-model="form.roleKey"></el-input>
        </el-form-item>
        <el-form-item label="角色顺序" prop="roleKey">
          <el-input v-model="form.roleSort"></el-input>
        </el-form-item>
        <el-form-item label="状态" prop="enable">
          <el-radio v-model="form.enable" :label="true">正常</el-radio>
          <el-radio v-model="form.enable" :label="false">停用</el-radio>
        </el-form-item>
      </div>
      <el-form-item label="菜单权限">
        <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
        <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
        <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
        <el-tree
          class="tree-border"
          :data="menuOptions"
          show-checkbox
          ref="menu"
          node-key="id"
          :check-strictly="!form.menuCheckStrictly"
          empty-text="加载中，请稍后"
          :props="defaultProps"
        />
      </el-form-item>
      <div class="search-form2">
        <el-form-item label="备注" prop="remark" style="width:100%;">
          <el-input v-model="form.remark" type="textarea" :rows="2"></el-input>
        </el-form-item>
      </div>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="close">取 消</el-button>
        <el-button type="primary" @click="submit">确 定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts">
import { useStore } from 'vuex'
import { reactive, watch, computed, toRefs, ref, defineComponent } from 'vue'
import { ElMessage } from 'element-plus'
import dialog from '@/mixins/dialog'
import { Role, StateType as RoleStateType } from '@/store/modules/system/role'
import { TreeSelect } from '@/store/modules/system/menu'

interface DataType {
  menuExpand: boolean;
  menuNodeAll: boolean;
  defaultProps: any;
  menuOptions: Array<TreeSelect>;
  form: Role;
  rules: object;
}

export default defineComponent({
  name: 'AURole',
  emits: ['onRefresh', 'close'], // this line
  props: {
    value: {
      type: Boolean,
      default: false
    }
  },
  setup(props, context) {
    const { dialogM } = dialog(props, context)
    const store = useStore<{role: RoleStateType}>()
    const data = reactive<DataType>({
      menuExpand: false,
      menuNodeAll: false,
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      menuOptions: [],
      form: {
        roleId: null,
        roleName: '',
        roleKey: '',
        roleSort: 1,
        menuCheckStrictly: true,
        enable: true,
        remark: ''
      },
      rules: {
        roleName: [
          { required: true, message: '角色名不能为空', trigger: 'blur' }
        ],
        roleKey: [
          { required: true, message: '权限字符不能为空', trigger: 'blur' }
        ],
        roleSort: [
          { required: true, message: '角色顺序不能为空', trigger: 'blur' }
        ]
      }
    })
    const menu = ref<HTMLElement>()
    const rulesForm = ref<HTMLElement>()
    const roleData = computed<Role>(() => {
      return store.state.role.data
    })
    const getTreeSelect = () => {
      store.dispatch('menu/getTreeSelect').then(res => {
        data.menuOptions = res.data
      })
    }
    const handleCheckedTreeExpand = (value: any, type: string) => {
      if (type === 'menu') {
        const treeList = data.menuOptions
        for (let i = 0; i < treeList.length; i++) {
          (menu.value as any).store.nodesMap[treeList[i].id].expanded = value
        }
      }
    }
    const handleCheckedTreeNodeAll = (value: any, type: string) => {
      if (type === 'menu') {
        (menu.value as any).setCheckedNodes(value ? data.menuOptions : [])
      }
    }
    const handleCheckedTreeConnect = (value: any, type: string) => {
      if (type === 'menu') {
        data.form.menuCheckStrictly = !!value
      }
    }
    // 所有菜单节点数据
    const getMenuAllCheckedKeys = () => {
      // 目前被选中的菜单节点
      const checkedKeys = (menu.value as any).getCheckedKeys()
      // 半选中的菜单节点
      const halfCheckedKeys = (menu.value as any).getHalfCheckedKeys()
      // eslint-disable-next-line prefer-spread
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
      return checkedKeys
    }
    const submit = () => {
      (rulesForm.value as any).validate((valid: boolean) => {
        if (valid) {
          data.form.menuIds = getMenuAllCheckedKeys()
          if (data.form && data.form.roleId) {
            store.dispatch('role/updateRole', data.form).then(() => {
              ElMessage({
                message: '更新成功',
                type: 'success'
              })
              context.emit('onRefresh')
              dialogM.close()
            })
          } else {
            store.dispatch('role/addRole', data.form).then(() => {
              ElMessage({
                message: '新增成功',
                type: 'success'
              })
              context.emit('onRefresh')
              dialogM.close()
            })
          }
        }
      })
    }
    watch(() => props.value, (val) => {
      if (!val) {
        data.form = {
          roleId: null,
          roleName: '',
          roleKey: '',
          roleSort: 1,
          menuCheckStrictly: true,
          enable: true,
          remark: ''
        }
        rulesForm.value && (rulesForm.value as any).resetFields()
      } else {
        if (roleData.value) {
          store.dispatch('menu/roleMenuTreeSelect', roleData.value.roleId).then(res => {
            data.menuOptions = res.menus
            menu.value && (menu.value as any).setCheckedKeys(res.checkedKeys)
          })
          data.form = JSON.parse(JSON.stringify(roleData.value))
        } else {
          getTreeSelect()
        }
      }
    })
    return {
      handleCheckedTreeConnect,
      handleCheckedTreeNodeAll,
      handleCheckedTreeExpand,
      menu,
      ...toRefs(data),
      ...toRefs(dialogM),
      rulesForm,
      submit
    }
  }
})
</script>
<style lang="scss" scoped>
/* tree border */
.tree-border {
    margin-top: 5px;
    border: 1px solid #e5e6e7;
    background: #FFFFFF none;
    border-radius:4px;
}
</style>
